package com.gudogudo.battleworm.model {
	import flash.text.TextField;	
	
	import com.gudogudo.battleworm.contact.ContactFilter;	
	
	import flash.events.*;	
	import flash.display.*;	
	import flash.ui.Keyboard;	
	import flash.net.URLRequest;

	import org.puremvc.as3.patterns.proxy.Proxy;
	import Box2D.Dynamics.*;
	import Box2D.Collision.*;	
	import Box2D.Common.Math.*;	

	import com.red.battleworm.AppMain;
	import com.gudogudo.battleworm.element.*;	
	import com.gudogudo.battleworm.map.Map;	
	import com.gudogudo.battleworm.contact.ContactListener;
	
	import Box2D.Collision.Shapes.b2Shape;	

	/**
	 * @author zhangs
	 */
	public class GameProxy extends Proxy {
		public var m_world:b2World;

		private var loader : Loader;
		private var map : Map;
		private var player : Player;
		private var bullet_list : Array;
		private var bullet_body_list : Array;
		
		public function GameProxy(proxyName : String) {
			super(proxyName, null);
		}
		
		public function loadMap(map_id : String, map_url : String) : void {
			if (facade.hasProxy(map_id)) {
				start(map_id);
				return;
			}
			
			var aURLRequest : URLRequest = new URLRequest(map_url);
			loader = new Loader();
			loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
			loader.contentLoaderInfo.addEventListener(Event.COMPLETE, 	function (e : Event) : void {
																			completeHandler(e, map_id);
																		});
			loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, progressHandler);
			loader.load(aURLRequest);
		}

		private function completeHandler(event:Event, map_id : String):void {
            trace("completeHandler: " + event);
            var map : Object = event.target.content;
			facade.registerProxy(new MapProxy(map_id, map));
			start(map_id);
		}

		private function ioErrorHandler(event:IOErrorEvent):void {
            trace("ioErrorHandler: " + event);
        }
        
        private function progressHandler(event:ProgressEvent):void {
            trace("progressHandler: bytesLoaded=" + event.bytesLoaded + " bytesTotal=" + event.bytesTotal);
        }
        
        private function start(map_id : String) : void {
			var worldAABB:b2AABB = new b2AABB();
			worldAABB.lowerBound.Set(-1000.0, -1000.0);
			worldAABB.upperBound.Set(1000.0, 1000.0);
			
			// Define the gravity vector
			var gravity:b2Vec2 = new b2Vec2(0.0, 16.0);
			
			// Allow bodies to sleep
			var doSleep:Boolean = true;
			
			// Construct a world object
			m_world = new b2World(worldAABB, gravity, doSleep);
//			m_world.SetContactListener(new ContactListener());
			m_world.SetContactFilter(new ContactFilter());
			// set debug draw
			var dbgDraw:b2DebugDraw = new b2DebugDraw();
			var dbgSprite:Sprite = new Sprite();
			AppMain.root.addChild(dbgSprite);
			dbgDraw.m_sprite = dbgSprite;
			dbgDraw.m_drawScale = 30.0;
			dbgDraw.m_fillAlpha = 0.3;
			dbgDraw.m_lineThickness = 1.0;
			dbgDraw.m_drawFlags = b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit;
			m_world.SetDebugDraw(dbgDraw);
			
			var aMapProxy : MapProxy = MapProxy(facade.retrieveProxy(map_id));
			aMapProxy.init(m_world);
			map = aMapProxy.getMap();
			
			bullet_list = new Array();
			bullet_body_list = new Array();
			
			var birth_array : Array = map.birth_array;
			var birth : Object = birth_array[uint(Math.random() * birth_array.length)];
			player = new Player(m_world, birth);
			
			tf = new TextField();
			tf.x = 100;
			tf.y = 30;
			tf.width = 200;
			tf.height = 24;
			tf.multiline = false;
			tf.border = true;
			AppMain.root.addChild(tf);
			AppMain.stage.addEventListener(Event.ENTER_FRAME, run);
			AppMain.stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandle);
			AppMain.stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandle);
			AppMain.stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandle);
			AppMain.stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandle);
        }
        
        private var tf : TextField;
        private function run(evt:Event):void {
			player.run();
			for each (var bullet : Bullet in bullet_list) {
				bullet.run();
			}
			m_world.Step(Box2DConfig.TIMESTEP, Box2DConfig.ITERATIONS);
			
			// Query the world for overlapping shapes.
			var k_maxCount:int = 10;
			var shapes:Array = new Array();
			var count:int = m_world.Query(player.getAABB(), shapes, k_maxCount);
			for (var i:int = 0; i < count; ++i)
			{
				var tShape:b2Shape = shapes[i] as b2Shape;
//				trace(i, tShape, tShape.GetBody());
				var f : Number = bullet_body_list.indexOf(tShape.GetBody());
				if (f>=0) {
					trace(f);
					tf.text = f+","+tf.text;
				}
			}
		}
        
        private function keyDownHandle(evt : KeyboardEvent) : void {
//        	trace(evt);
        	switch(evt.keyCode) {
        		case Keyboard.LEFT:
        			player.setSpeed(Player.LEFTSPEED);
					break;
        		case Keyboard.RIGHT:
					player.setSpeed(Player.RIGHTSPEED);
					break;
				default:
//					player.playActions();
        	}
        }
        
        private function keyUpHandle(evt : KeyboardEvent) : void {
			player.setSpeed(AbstractElement.NONESPEED);
        }
        
        private function mouseMoveHandle(evt : MouseEvent) : void {
			player.updateArrow(evt);
        }
        
        private function mouseDownHandle(evt : MouseEvent) : void {
//        	trace(evt);
        	var bullet : Bullet = new Bullet(m_world, player.getPosition().x, player.getPosition().y, player.arrow_rotation, player.scale);
			
			if (bullet_list.length >= 20) {
//				m_world.DestroyBody((bullet_list[0] as Bullet).body);
				m_world.DestroyBody(bullet_body_list[0] as b2Body);
				bullet_list.shift();
				bullet_body_list.shift();
			}
			bullet_list.push(bullet);
			bullet_body_list.push(bullet.body);
		}
	}
}